# Python GPIO开发 ***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.*** --- # python-periphery简介 **python-periphery** 是一个用于在Linux系统上通过Python进行硬件外设(GPIO、SPI、I2C等)开发的库。 ## 主要特点 - **基于Linux内核接口**:使用标准的Linux字符设备接口(如 */dev/gpiochip0*) - **跨平台兼容性**:适用于各种Linux单板计算机(Raspberry Pi、BeagleBone、Radxa等) - **纯Python实现**:不需要编译C扩展,易于安装和部署 - **支持多种外设**:GPIO、SPI、I2C、MMIO、Serial、PWM等 ## 支持的外设类型 | **外设类型** | **说明** | | --- | --- | | GPIO | 通用输入输出 | | SPI | 串行外设接口 | | I2C | I²C总线通信 | | MMIO | 内存映射I/O | | Serial | 串口通信 | | PWM | 脉宽调制 | # 安装python-periphery ## 安装pip3 首先确保系统已安装pip3: ```bash sudo apt update sudo apt install python3-pip -y ``` ## 安装python-periphery库 由于Python 3.13+的PEP 668保护机制,需要使用 *--break-system-packages* 参数: ```bash pip3 install python-periphery --break-system-packages ``` 验证安装: ```plaintext python3 -c "from periphery import GPIO; print('Installation successful!')" ``` > **提示**:对于嵌入式开发板,使用 *--break-system-packages* 参数是安全的。如果您更倾向于使用虚拟环境,可以参考 [Python虚拟环境使用](<../Python虚拟环境使用/Python虚拟环境使用.md>) 文档。 # GPIO读取 > **重要提示**:Pin3和Pin5默认配置为I2C9接口(SDA和SCL),如果需要作为GPIO使用,请确保没有其他设备正在占用这些引脚。 ## 硬件准备 - 主板 - 杜邦线 ## 软件准备 ### 测试代码 以下代码使用python-periphery库来读取Pin3 (GPIO36)引脚的高低电平。 创建文件 *gpio_input.py*: ```python from periphery import GPIO import time def read_gpio_input():# Configure GPIO input (modify pin number according to actual hardware)# Pin3 corresponds to GPIO36 (pin 36 of /dev/gpiochip4)try:# Initialize GPIO in input mode gpio_in = GPIO("/dev/gpiochip4", 36, "in")print("Starting GPIO input reading (press Ctrl+C to exit)")while True:# Read pin value value = gpio_in.read()print(f"GPIO input value: {value} (True=High, False=Low)") time.sleep(1) # Read once per secondexcept KeyboardInterrupt:print("\nProgram exited")except Exception as e:print(f"Error occurred: {e}")finally:# Ensure resources are releasedtry: gpio_in.close()except:passif __name__ == "__main__": read_gpio_input() ``` ## 测试步骤 1. 将Pin3 (GPIO36)引脚接GND或3.3V引脚 2. 将代码保存为 *gpio_input.py* 3. 使用以下命令运行测试代码: ```bash python3 gpio_input.py ``` ## 实验现象 终端会输出 *False* 或 *True* 信息: - *False* 代表低电平(引脚接GND) - *True* 代表高电平(引脚接3.3V) 示例输出: ```plaintext Starting GPIO input reading (press Ctrl+C to exit) GPIO input value: False (True=High, False=Low) GPIO input value: False (True=High, False=Low) GPIO input value: True (True=High, False=Low) ``` # GPIO输出 ## 硬件准备 - 主板 - 杜邦线 ## 软件准备 ### 测试代码 以下代码使用python-periphery库来控制Pin3 (GPIO36)引脚输出高低电平,然后通过Pin5 (GPIO37)引脚读取Pin3引脚的高低电平。 创建文件 *gpio_output.py*: ```python from periphery import GPIO import time def gpio_output_with_feedback():# GPIO Configuration (modify pin numbers based on your hardware)# Pin3/GPIO36 (output) → maps to pin 36 of /dev/gpiochip4# Pin5/GPIO37 (input) → maps to pin 37 of /dev/gpiochip4 OUTPUT_PIN_CHIP = "/dev/gpiochip4" OUTPUT_PIN_NUMBER = 36 # Pin3/GPIO36 (output pin, controlled by the script) INPUT_PIN_NUMBER = 37 # Pin5/GPIO37 (input pin, reads output state)# Initialize GPIO objects as None first (for safe release later) gpio_out = None gpio_in = Nonetry:# Initialize Pin3/GPIO36 as OUTPUT mode gpio_out = GPIO(OUTPUT_PIN_CHIP, OUTPUT_PIN_NUMBER, "out")# Initialize Pin5/GPIO37 as INPUT mode gpio_in = GPIO(OUTPUT_PIN_CHIP, INPUT_PIN_NUMBER, "in")# Print test initialization infoprint("=== GPIO Output-Input Feedback Test Started ===")print(f"Controlled Pin (GPIO36): {OUTPUT_PIN_CHIP} - Pin {OUTPUT_PIN_NUMBER} (OUTPUT)")print(f"Monitoring Pin (GPIO37): {OUTPUT_PIN_CHIP} - Pin {INPUT_PIN_NUMBER} (INPUT)")print("Test Behavior: GPIO36 toggles HIGH/LOW every 1s; GPIO37 verifies GPIO36's state")print("Press Ctrl+C to stop the test\n")# Main loop: Toggle GPIO36 and read GPIO37 feedbackwhile True:# 1. Set GPIO36 to HIGH level gpio_out.write(True) time.sleep(0.1) # Short delay for signal stabilization (avoid read lag) gpio37_reading = gpio_in.read()print(f"GPIO36 Output: HIGH (True) | GPIO37 Reading: {gpio37_reading}")# Keep GPIO36 HIGH for 1 second time.sleep(1)# 2. Set GPIO36 to LOW level gpio_out.write(False) time.sleep(0.1) # Short delay for signal stabilization gpio37_reading = gpio_in.read()print(f"GPIO36 Output: LOW (False) | GPIO37 Reading: {gpio37_reading}")# Keep GPIO36 LOW for 1 second time.sleep(1)# Handle user-initiated exit (Ctrl+C)except KeyboardInterrupt:print("\n\nTest stopped by user (Ctrl+C)")# Handle other unexpected errors (e.g., GPIO access failure)except Exception as e:print(f"\nError during test: {str(e)}")# Ensure GPIO resources are released even if an error occursfinally:print("\nReleasing GPIO resources...")# Safely close GPIO36 (set to LOW first to avoid residual high level)if gpio_out:try: gpio_out.write(False) gpio_out.close()print(f"Successfully closed GPIO36 (Pin {OUTPUT_PIN_NUMBER})")except Exception as close_err:print(f"Failed to close GPIO36 (Pin {OUTPUT_PIN_NUMBER}): {str(close_err)}")# Safely close GPIO37if gpio_in:try: gpio_in.close()print(f"Successfully closed GPIO37 (Pin {INPUT_PIN_NUMBER})")except Exception as close_err:print(f"Failed to close GPIO37 (Pin {INPUT_PIN_NUMBER}): {str(close_err)}")print("Resource release complete.")# Run the test when the script is executed directlyif __name__ == "__main__": gpio_output_with_feedback() ``` ## 测试步骤 1. 将Pin3 (GPIO36)引脚和Pin5 (GPIO37)引脚进行短接 2. 将代码保存为 *gpio_output.py* 3. 使用以下命令运行测试代码: ```bash sudo python3 gpio_output.py ``` > **注意**:GPIO输出可能需要root权限,因此使用 *sudo* 运行。 ## 实验现象 终端会输出 *False* 或 *True* 信息: - *False* 代表低电平 - *True* 代表高电平 示例输出: ```plaintext === GPIO Output-Input Feedback Test Started === Controlled Pin (GPIO36): /dev/gpiochip4 - Pin 36 (OUTPUT) Monitoring Pin (GPIO37): /dev/gpiochip4 - Pin 37 (INPUT) Test Behavior: GPIO36 toggles HIGH/LOW every 1s; GPIO37 verifies GPIO36's state Press Ctrl+C to stop the test GPIO36 Output: HIGH (True) | GPIO37 Reading: True GPIO36 Output: LOW (False) | GPIO37 Reading: False GPIO36 Output: HIGH (True) | GPIO37 Reading: True GPIO36 Output: LOW (False) | GPIO37 Reading: False ``` # GPIO引脚映射说明 在python-periphery中,你需要为GPIO引脚指定两个参数: 1. **GPIO芯片设备**:Quectel Pi H1主要使用 */dev/gpiochip4* 2. **引脚编号**:物理引脚对应的GPIO编号 ## 40Pin引脚映射示例 | **物理引脚标识** | **引脚名称** | **GPIO编号** | **GPIO芯片** | **引脚编号** | **默认功能** | | --- | --- | --- | --- | --- | --- | | Pin3 | NFC_I2C_SDA | GPIO36 | /dev/gpiochip4 | 36 | I2C09_SDA | | Pin5 | NFC_I2C_SCL | GPIO37 | /dev/gpiochip4 | 37 | I2C09_SCL | | Pin7 | CAM2_RST | GPIO77 | /dev/gpiochip4 | 77 | GPIO | | Pin11 | GPIO_16 | GPIO16 | /dev/gpiochip4 | 16 | GPIO/SPI/UART/I2C | | Pin13 | GPIO_17 | GPIO17 | /dev/gpiochip4 | 17 | GPIO/SPI/UART/I2C | ## 查看可用GPIO 使用 *gpioinfo* 命令查看所有可用的GPIO芯片和引脚: ```bash # 安装gpiod工具sudo apt install gpiod -y # 查看所有GPIO信息 gpioinfo # 查看特定芯片 gpioinfo /dev/gpiochip4 ``` # 常见问题 ## 权限问题 如果遇到权限错误,可以: 1. 使用 *sudo* 运行脚本 2. 将用户添加到 *gpio* 用户组: ```bash sudo usermod -a -G gpio $USER ``` 3. 注销并重新登录使权限生效 ## 引脚占用问题 如果遇到 *[Errno 16] Device or resource busy* 或 *[Errno 1] Operation not permitted* 错误: **检查引脚状态:** ```bash # 查看所有GPIO引脚状态 gpioinfo | grep "consumer="# 查看特定芯片的引脚占用情况 gpioinfo /dev/gpiochip4 | grep -E "(line|consumer)" ``` **常见原因:** - 引脚被其他进程占用(如I2C、SPI等) - 引脚已被系统功能使用 - 其他GPIO程序正在运行 **解决方法:** - 选择未被占用的引脚(gpioinfo中显示为 *input* 且无 *consumer* 的引脚) - 如果你需要使用被占用的引脚,需要禁用相应的功能 ## 引脚编号错误 如果遇到 *[Errno 22] Invalid argument* 错误: **原因:** - 引脚编号不存在或不可用 - 使用了错误的GPIO芯片设备 **解决方法:** 1. 使用 *gpioinfo* 查看实际可用的引脚编号 2. 确认使用正确的GPIO芯片(Quectel Pi H1主要使用 */dev/gpiochip4*) ## 调试技巧 **查看可用的GPIO芯片:** ```bash ls -l /dev/gpiochip* ``` **查看GPIO芯片详细信息:** ```bash gpioinfo ``` **测试特定引脚:** ```bash # 使用gpioget读取引脚值sudo gpioget /dev/gpiochip4 36# 使用gpioset设置引脚值sudo gpioset /dev/gpiochip4 36=1 # 设置为高电平sudo gpioset /dev/gpiochip4 36=0 # 设置为低电平 ``` # 参考资源 - [python-periphery GitHub仓库]() - [python-periphery官方文档]() - [40-Pin扩展](<../../使用指南/40-Pin扩展/40-Pin扩展.md>) - [Python虚拟环境使用](<../Python虚拟环境使用/Python虚拟环境使用.md>) - [C/C++ GPIO开发](<../C_C++ GPIO开发/C_C++ GPIO开发.md>)